package fei.typhoon.engine.android.sprite;

import fei.typhoon.engine.android.FeiSprite;
import fei.typhoon.engine.utils.FeiColor;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Shader;


public class FeiGeometry extends FeiSprite {

	public enum ViewShape {
		/** 矩形 */
		RECT_RIGHT,
		/** 圆角矩形 */
		RECT_FILLET,
		/** 斜角矩形 */
		RECT_BEVEL,
		/** 圆 */
		ROUND,
		/** 椭圆 */
		ELLIPSE;
	}

	public final static int DEFAULT_RGB_STEP = 0x04;

	
	/** 用于获取系统及屏幕属性 */
	protected Context context = null;
	/** 形状 */
	protected ViewShape shape = ViewShape.RECT_RIGHT;
	/** 宽 */
	protected int width = 0;
	/** 高 */
	protected int height = 0;
	/** x坐标，屏幕左上角为原点0 */
	protected int x = 0;
	/** y坐标，屏幕左上角为原点0 */
	protected int y = 0;
	/** Rect区域，由x,y坐标和宽高决定 */
	protected RectF rect = null;
	/** 透明度 */
	protected int alpha = 0xFF;
	/** 包括颜色的alpha值，如0xFF010203 */
	protected int color = 0xFF000000;
	/** 渐变颜色集 */
	protected int[] colors = null;
	/** 颜色渐变间隔 */
	protected float rgbStep = DEFAULT_RGB_STEP;
	/** 标志渐变颜色被设置 */
	protected boolean colorsChanged = false;
	/**
	 * 颜色值的个数，默认值为height，则每隔一个像素变化一个颜色。使用举例，如height=24，想每隔3个像素变化一个颜色值，
	 * 则colorCounts=8
	 */
	private int colorCounts = height;

	private FeiEdge edge = null;

	private FeiGeometry() {
		paint = new Paint();
		paint.setAntiAlias(true);
		paint.setAlpha(alpha);
		paint.setColor(color);
	}

	public FeiGeometry(Context context) {
		this.context = context;
		paint = new Paint();
		paint.setAntiAlias(true);
		paint.setAlpha(alpha);
		paint.setColor(color);
	}

	public FeiGeometry(Context context, int width, int height, int x, int y) {
		this(context);
		colorCounts = height;
		reset(width, height, x, y);
	}

	/**
	 * @param canvas
	 */
	protected void drawx(Canvas canvas){
		
	}

	/**
	 * 用于重设paint等，会在绘图前调用
	 */
	protected void reset() {
		paint.setAlpha(alpha);
		paint.setColor(color);
		if (colors != null && colorsChanged) {
			colorsChanged = false;
			if (colors.length > 2) {
				// 着色器，这里是使用的线性渐变(LinearGradient)
				// 其他着色方式有径向渐变(RadialGradient)，扫描渐变(SweepGradient)，混合着色(ComposeShader)
				Shader shader = new LinearGradient(x, y, x, y + height, colors,
						null, Shader.TileMode.REPEAT);
				paint.setShader(shader);
			}
		}
	}

	/**
	 * 绘制形状
	 * 
	 * @param canvas
	 */
	protected void drawShape(Canvas canvas, Paint paint) {
		switch (shape) {
		case RECT_FILLET:
			int b = (width >= height) ? width : height;
			int rr = getArcPixs(b);
			if (rect == null) {
				rect = new RectF(x, y, x + width, y + height);
			} else {
				rect.left = x;
				rect.top = y;
				rect.right = x + width;
				rect.bottom = y + height;
			}
			canvas.drawRoundRect(rect, rr, rr, paint);
			break;
		case RECT_BEVEL:
			Path bevelPath = new Path();
			int rb = (width >= height) ? width : height;
			int arcPixs = getArcPixs(rb);
			bevelPath.moveTo(x, y + arcPixs);
			bevelPath.lineTo(x + arcPixs, y);
			bevelPath.lineTo(x + width - arcPixs, y);
			bevelPath.lineTo(x + width, y + arcPixs);
			bevelPath.lineTo(x + width, y + height - arcPixs);
			bevelPath.lineTo(x + width - arcPixs, y + height);
			bevelPath.lineTo(x + arcPixs, y + height);
			bevelPath.lineTo(x, y + height - arcPixs);
			bevelPath.lineTo(x, y + arcPixs);
			bevelPath.close();
			canvas.drawPath(bevelPath, paint);
			break;
		case ROUND:
			int r = (width <= height) ? (width / 2) : (height / 2);
			canvas.drawCircle(x + r, y + r, r, paint);
			break;
		case ELLIPSE:
			if (rect == null) {
				rect = new RectF(x, y, x + width, y + height);
			} else {
				rect.left = x;
				rect.top = y;
				rect.right = x + width;
				rect.bottom = y + height;
			}
			canvas.drawOval(rect, paint);
			break;
		default:
			canvas.drawRect(x, y, x + width, y + height, paint);
			break;
		}
	}

	protected void drawEdge(Canvas canvas) {
		if (edge != null) {
			drawShape(canvas, edge.getPaint());
		}
	}

	public final void draw(Canvas canvas) {
		reset();
		drawShape(canvas, paint);
		drawEdge(canvas);
		drawx(canvas);
	}

	public void setLocation(int x, int y) {
		this.x = x;
		this.y = y;
	}

	public void setSize(int width, int height) {
		this.width = width;
		this.height = height;
	}

	/**
	 * 用于外部调用设置view的位置，大小
	 * 
	 * @param width
	 * @param height
	 * @param x
	 * @param y
	 */
	public void reset(int width, int height, int x, int y) {
		setLocation(x, y);
		setSize(width, height);
	}

	public void setEdge(int color, float strokeWidth) {
		if (edge == null) {
			edge = new FeiEdge(strokeWidth);
			edge.setColor(color);
		} else {
			if (strokeWidth > 0) {
				edge.setStrokeWidth(strokeWidth);
				edge.setColor(color);
			} else {
				edge = null;
			}
		}
	}

	public void setEdgeColor(int color) {
		if (edge != null) {
			edge.setColor(color);
		}
	}
	
	public void setEdgeAlpha(int alpha) {
		if (edge != null) {
			edge.setAlpha(alpha);
		}
	}

	public void setEdgeWidth(float strokeWidth) {
		if (edge == null) {
			edge = new FeiEdge(strokeWidth);
		} else {
			if (strokeWidth > 0) {
				edge.setStrokeWidth(strokeWidth);
			} else {
				edge = null;
			}
		}
	}

	/**
	 * @param topColor
	 *            顶端颜色，color包括颜色的alpha值，如0xFF010203， R,G,B将采用默认的步骤偏移量
	 */
	public void setColors(int topColor) {
		setColors(FeiColor.getGradientColors(color, colorCounts, rgbStep,
				rgbStep, rgbStep));
	}

	/**
	 * @param topColor
	 *            顶端颜色，color包括颜色的alpha值，如0xFF010203，R,G,B将采用默认的步骤偏移量
	 * @param gradient
	 *            渐变方向
	 * @param colorBack
	 *            是否回滚
	 */
	public void setColors(int topColor, byte gradient, boolean colorBack) {
		setColors(FeiColor.getGradientColors(color, colorCounts, rgbStep,
				rgbStep, rgbStep, gradient, colorBack));
	}

	/**
	 * @param topColor
	 *            顶端颜色，color包括颜色的alpha值，如0xFF010203
	 * @param bottomColor
	 *            底端颜色
	 */
	public void setColors(int topColor, int bottomColor) {
		setColors(FeiColor.getGradientColors(topColor, bottomColor,
				colorCounts));
	}

	/**
	 * @param topColor
	 *            顶端颜色，color包括颜色的alpha值，如0xFF010203
	 * @param rgbStep
	 *            R,G,B渐变步骤偏移量
	 */
	public void setColors(int topColor, float rgbStep) {
		setRgbStep(rgbStep);
		setColors(FeiColor.getGradientColors(topColor, colorCounts,
				rgbStep, rgbStep, rgbStep));
	}

	/**
	 * @param topColor
	 *            顶端颜色，color包括颜色的alpha值，如0xFF010203
	 * @param rgbStep
	 *            R,G,B渐变步骤偏移量
	 * @param gradient
	 *            渐变方向
	 * @param colorBack
	 *            是否回滚
	 */
	public void setColors(int topColor, float rgbStep, byte gradient,
			boolean colorBack) {
		setRgbStep(rgbStep);
		setColors(FeiColor.getGradientColors(topColor, colorCounts,
				rgbStep, rgbStep, rgbStep, gradient, colorBack));
	}

	/**
	 * @param topColor
	 *            顶端颜色，color包括颜色的alpha值，如0xFF010203
	 * @param stepR
	 *            R渐变步骤偏移量
	 * @param stepG
	 *            G渐变步骤偏移量
	 * @param stepB
	 *            B渐变步骤偏移量
	 */
	public void setColors(int topColor, float stepR, float stepG, float stepB) {
		setColors(FeiColor.getGradientColors(topColor, colorCounts,
				stepR, stepG, stepB));
	}

	/**
	 * @param topColor
	 *            顶端颜色，color包括颜色的alpha值，如0xFF010203
	 * @param stepR
	 *            R渐变步骤偏移量
	 * @param stepG
	 *            G渐变步骤偏移量
	 * @param stepB
	 *            B渐变步骤偏移量
	 * @param gradient
	 *            渐变方向
	 * @param colorBack
	 *            是否回滚
	 */
	public void setColors(int topColor, float stepR, float stepG, float stepB,
			byte gradient, boolean colorBack) {
		setColors(FeiColor.getGradientColors(topColor, colorCounts,
				stepR, stepG, stepB, gradient, colorBack));
	}

	public ViewShape getShape() {
		return shape;
	}

	public void setShape(ViewShape shape) {
		this.shape = shape;
	}

	public int getWidth() {
		return width;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	public Paint getPaint() {
		return paint;
	}

	public void setPaint(Paint paint) {
		this.paint = paint;
	}

	public int getAlpha() {
		return alpha;
	}

	public void setAlpha(int alpha) {
		this.alpha = alpha;
	}

	public int getColor() {
		return color;
	}

	public void setColor(int color) {
		this.color = color;
	}

	public int[] getColors() {
		return colors;
	}

	/**
	 * 自定义的一组颜色值，color包括颜色的alpha值，如0xFF010203
	 */
	public void setColors(int[] custemColors) {
		this.colors = custemColors;
		colorsChanged = true;
	}

	public float getRgbStep() {
		return rgbStep;
	}

	public void setRgbStep(float rgbStep) {
		this.rgbStep = rgbStep;
	}

	public int getColorCounts() {
		return colorCounts;
	}

	public void setColorCounts(int colorCounts) {
		this.colorCounts = colorCounts;
	}
	
	/**
	 * 计算圆弧的半径
	 * @param lineLength 与圆弧相接的直线长度
	 * @return
	 */
	public int getArcPixs(float lineLength) {
		int pixs = 0;
		float tempFloat = lineLength / 20.0f;
		int tempInt = (int) tempFloat;
		if (tempFloat - (float) tempInt >= 0.5f) {
			pixs = tempInt + 1;
		} else {
			pixs = tempInt;
		}
		return pixs;
	}
	
	@Override
	public void pause() {
		
	}

	@Override
	public void resume() {
		
	}
	
	@Override
	public void destroy() {
		
	}

	class FeiEdge extends FeiGeometry {
		private float strokeWidth = 1;

		public FeiEdge(float strokeWidth) {
			super();
			this.strokeWidth = strokeWidth;
			paint.setStyle(Paint.Style.STROKE);
			paint.setStrokeWidth(strokeWidth);
		}

		@Override
		protected void drawx(Canvas canvas) {
		}

		public float getStrokeWidth() {
			return strokeWidth;
		}

		public void setStrokeWidth(float strokeWidth) {
			this.strokeWidth = strokeWidth;
			paint.setStrokeWidth(strokeWidth);
		}

		public void setColor(int color) {
			this.color = color;
			paint.setColor(color);
		}

		public void setAlpha(int alpha) {
			this.alpha = alpha;
			paint.setAlpha(alpha);
		}
	}

	@Override
	public boolean touchDown(float x, float y) {
		return false;
	}

	@Override
	public boolean touchMove(float x, float y) {
		return false;
	}

	@Override
	public boolean touchUp(float x, float y) {
		return false;
	}
	

	@Override
	public boolean onTouchDown(float x, float y) {
		return false;
	}

	@Override
	public boolean onTouchMove(float x, float y) {
		return false;
	}

	@Override
	public boolean onTouchUp(float x, float y) {
		return false;
	}
}
